﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace WindowsFormsApplication1
{
    public enum ProjectFileType
    {
        SourceFile,
        HeaderFile
    }

    public class ProjectFile
    {
        public string Path;
        public string Commandline;
        public string OutputFile;

        public string Filename
        {
            get { return System.IO.Path.GetFileName(Path); }
        }

        public ProjectFileType Type
        { 
            get
            { 
                return System.IO.Path.GetExtension(Path) == ".c" 
                    ? ProjectFileType.SourceFile 
                    : ProjectFileType.HeaderFile;
            }
        }
        
        public ProjectFile(string path, string cmd, string output)
        {
            Path = path;
            Commandline = cmd;
            OutputFile = output;
        }
    }

    public class ProjectFileAddedArgs : EventArgs
    {
        public ProjectFile ProjectFile;

        public ProjectFileAddedArgs(ProjectFile p) { ProjectFile = p; }
    }

    public class Project
    {
        public List<ProjectFile> Files { get; private set; }

        public delegate void ProjectFileAddedHandler(object sender, ProjectFileAddedArgs e);
        public event ProjectFileAddedHandler ProjectFileAdded;

        public string Directory { get; private set; }

        private const string defaultCommandlineArguments = @"-Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o";

        public void Load(string filename)
        {
            Files =
                (from e in XDocument.Load(filename).Root.Descendants("File")
                where System.IO.File.Exists((string)e.Attribute("Path"))
                select new ProjectFile(
                    (string)e.Attribute("Path"),
                    (string)e.Attribute("CompilerArguments"),
                    (string)e.Attribute("Output"))).ToList<ProjectFile>();

            Directory = System.IO.Path.GetDirectoryName(filename);

            if (ProjectFileAdded != null)
                foreach (ProjectFile p in Files)
                    ProjectFileAdded(this, new ProjectFileAddedArgs(p));
        }

        public void AddNewFile(string filename)
        {
            ProjectFile p = new ProjectFile(
                System.IO.Path.Combine(Directory, filename),
                defaultCommandlineArguments,
                System.IO.Path.GetFileNameWithoutExtension(filename) + ".o");

            System.IO.File.Create(p.Path);

            Files.Add(p);

            if (ProjectFileAdded != null)
                ProjectFileAdded(this, new ProjectFileAddedArgs(p));
        }

        public void Save(string filename)
        {
            new XElement("Project",
                new XElement("Files",
                    from f in Files
                    select new XElement("File", new XAttribute[] {
                        new XAttribute("Path", f.Path),
                        new XAttribute("CompilerArguments", f.Commandline),
                        new XAttribute("Output", f.OutputFile)})))
                            .Save(filename);
        }

        internal bool HasFilename(string filename)
        {
            foreach (ProjectFile p in Files) 
                if (p.Filename.ToLowerInvariant() == filename.ToLowerInvariant()) 
                    return true;
            return false;
        }
    }
}
